﻿--Cuando un usuario inicia sesion 
CREATE SEQUENCE pca_log.seq_sesion_id;
CREATE TABLE pca_log.sesiones
(
	empresa_id varchar(2) NOT NULL,
	oficina_id varchar(2) NOT NULL,
	sesion_id bigint NOT NULL DEFAULT pca_global.fn_pseudo_encrypt_bigint(nextval('pca_log.seq_sesion_id')::integer),
	zona_horaria varchar(50) NOT NULL,
	usuario_id character(36) NOT NULL,
	ip varchar(45) NOT NULL,--el ip con el que se inicia sesion
	fecha_hora timestamp with time zone NOT NULL DEFAULT current_timestamp,--la fecha y hora de inicio de sesion
	CONSTRAINT sesiones_pk PRIMARY KEY(empresa_id,oficina_id,sesion_id),
	CONSTRAINT oficinas_fkey FOREIGN KEY(empresa_id,oficina_id)
		REFERENCES pca.oficinas(empresa_id,oficina_id) MATCH FULL
		ON UPDATE CASCADE ON DELETE CASCADE,
	CONSTRAINT sesion_id_unq UNIQUE(sesion_id),
	CONSTRAINT usuarios_fkey FOREIGN KEY(usuario_id)
		REFERENCES pca_membership."Users"("pId")
		ON UPDATE CASCADE ON DELETE CASCADE
);

-----------------------------------------------------------------------------------------------
-----------------------------------------Vistas------------------------------------------------
-----------------------------------------------------------------------------------------------

CREATE OR REPLACE VIEW pca_log.vw_sesiones AS
SELECT
	s.empresa_id,
	e.nombre AS empresa,
	s.oficina_id,
	o.nombre AS oficina,
	s.sesion_id,
	s.usuario_id,
	u."Username" AS usuario,
	s.ip,
	s.fecha_hora
FROM
	pca_log.sesiones s
INNER JOIN
	pca.oficinas o
ON
	(s.oficina_id=o.oficina_id AND
	 s.empresa_id=o.empresa_id)
INNER JOIN
	pca.empresas e
ON
	(o.empresa_id=e.empresa_id)
INNER JOIN
	pca_membership."Users" u
ON
	(s.usuario_id=u."pId");

-----------------------------------------------------------------------------------------------
-------------------------------------pca_log.sesiones------------------------------------------
-----------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION pca_log.fn_add_sesion(varchar,--empresa_id $1
						 varchar,--oficina_id $2
						 character,--usuario_id $3
						 varchar --ip $4
						 )RETURNS bigint AS
$$
DECLARE
	current_sesion timestamp with time zone;
	ultima_sesion timestamp with time zone;
	row_usuario pca.vw_usuarios%ROWTYPE;
	
BEGIN
	--Consultamos la ultima sesion para comparar que la fecha no sea inferior a la fecha actual
	SELECT 
		valor::timestamp with time zone 
	INTO
		ultima_sesion
	FROM 
		pca_tablas.fn_get_configuracion('UltimaSesion');
		
	current_sesion := current_timestamp;
	
	IF (FOUND) THEN
		IF(current_sesion > ultima_sesion)THEN

			SELECT
				*
			INTO
				row_usuario
			FROM
				pca.vw_usuarios
			WHERE
				empresa_id=$1 AND
				oficina_id=$2 AND
				usuario_id=$3;

			IF(FOUND) THEN
				PERFORM pca_tablas.fn_update_configuracion('UltimaSesion',current_sesion::text);
				
				INSERT INTO pca_log.sesiones
					(empresa_id,
					oficina_id,
					zona_horaria,
					usuario_id,
					ip)
				VALUES
					($1,$2,row_usuario.zona_horaria,$3,$4);
					
				RETURN  pca_global.fn_pseudo_encrypt_bigint(currval('pca_log.seq_sesion_id')::integer);
			ELSE
				RAISE EXCEPTION 'Usuario no autorizado para la empresa-oficina asignada';
			END IF;
		ELSE
			RAISE EXCEPTION 'La fecha actual es menor que la ultima fecha de uso revisar fecha del servidor';
		END IF;
	ELSE
		RAISE EXCEPTION 'Error al consultar fecha-hora de la ultima sesion';
	END IF;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_log.fn_get_sesion(bigint --sesion_id $1
						 )RETURNS SETOF pca_log.vw_sesiones AS
$$
DECLARE
	_row pca_log.vw_sesiones%ROWTYPE;
BEGIN
	FOR _row IN
		SELECT
			*
		FROM
			pca_log.vw_sesiones
		WHERE
			sesion_id = $1
	LOOP
		RETURN NEXT _row;
	END LOOP;
END;
$$
LANGUAGE plpgsql;